package org.sardine.aop;

import java.util.List;
import java.lang.reflect.Constructor;
import java.util.ArrayList;

import org.sardine.util.Assert;
import org.sardine.util.ClassUtils;

import net.sf.cglib.proxy.Enhancer;

public class CglibAopProxy implements AopProxy{
	
	private ProxySupport support;
	private Class targetClass;
	private Object[] constructorArgs;
	private Class[] constructorArgTypes;
	
	public CglibAopProxy(ProxySupport support){
		this.support = support;
	}

	public Object getProxy() {
		return getProxy(ClassUtils.getDefaultClassLoader());
	}

	public Object getProxy(ClassLoader classLoader) {
		
		Object proxy;
		
		Object target = support.getTarget();
		if(target != null){
			targetClass = target.getClass();
		}else{
			targetClass = support.getTargetClass();
		}
		
		Enhancer enhancer = new Enhancer();
		
		if(classLoader != null){
			enhancer.setClassLoader(classLoader);
		}
		
		if(targetClass != null){
			enhancer.setSuperclass(targetClass);
		}else{
			throw new NullPointerException("target或targetClass不能为null");
		}
		
		enhancer.setCallback(new CglibMethodInterceptor(this.support));
		//enhancer.setInterceptDuringConstruction(false);
		
		if(this.constructorArgs != null){
			proxy = enhancer.create(this.constructorArgTypes,this.constructorArgs);
			//proxy = enhancer.create(new Class[]{String.class},new Object[]{"001_test"});
		}else{
			proxy = enhancer.create();
		}
		
		return proxy;
	}

	public Object getProxy(Object[] targetConstructorParameters) {
		
		if(targetConstructorParameters!=null && targetConstructorParameters.length > 0){
			int plength = targetConstructorParameters.length;
			Class[] pclasses = new Class[plength];
			for(int i=0;i<plength;i++){
				pclasses[i] = targetConstructorParameters[i].getClass();
			}
			this.constructorArgTypes = pclasses;
			this.constructorArgs = targetConstructorParameters;
		}
		
		return getProxy();
	}

	public Object[] getConstructorArgs() {
		return constructorArgs;
	}

	public Class[] getConstructorArgTypes() {
		return constructorArgTypes;
	}

	public void setConstructorArgs(Object[] constructorArgs) {
		this.constructorArgs = constructorArgs;
	}

	public void setConstructorArgTypes(Class[] constructorArgTypes) {
		this.constructorArgTypes = constructorArgTypes;
	}
	
	


}
